package com.tju.resource.server.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tju.resource.mapper.*;
import com.tju.resource.model.*;
import com.tju.resource.server.SysParamsService;
import com.tju.resource.server.TbCommandService;
import com.tju.resource.server.TbOrderService;
import com.tju.resource.tool.result.Result;
import com.tju.resource.tool.result.ResultEnum;
import com.tju.resource.tool.result.ResultUtil;
import com.tju.resource.tool.tool.ChineseExceptionUtils;
import com.tju.resource.tool.tool.ClientParameters;
import com.tju.resource.tool.tool.EmptyUtils;
import com.tju.resource.tool.tool.QuickQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

@Service
public class TbCommandServiceImpl implements TbCommandService {

    private static int cmdNumberIndex = 0; //指令下标
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    @Autowired
    private TbCommandMapper tbCommandMapper;
    @Autowired
    private TbCmdOrderMapper tbCmdOrderMapper;
    @Autowired
    private TbOrderMapper tbOrderMapper;
    @Autowired
    private SysParamsService paramsServiceService;
    @Autowired
    private ChineseExceptionUtils zh_CH;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private TbRawMatlMapper tbRawMatlMapper;
    @Autowired
    private TbOrderService tbOrderService;

    /**
     * 新增指令信息
     *
     * @param command 指令信息
     * @return 结果
     */
    @Override
    @Transactional
    public Result<Object> insertCommand(TbCommand command) {
        try {
            String cmdNumber = command.getCmdNumber(); //指令号
            String createBy = command.getCreateBy();//创建人
            //TbOrder tbOrder = tbOrderService.checkOrderNumberUnique(command.getOrderNumber());
//            long data = (command.getDelivery().getTime() - sdf.parse(sdf.format(new Date())).getTime()) / (24 * 3600 * 1000);  //算出来距离几天
//            long paramsValue = Long.parseLong(paramsServiceService.get("CMD_DELIVERY").getParamsValue());  //拿到你设置多少天交期
//            if (data < paramsValue) {
//                return ResultUtil.success(ResultEnum.UNKONW_ERROR, "交期时间必须大于指令时间：" + paramsValue + "天");
//            }
//            if (EmptyUtils.isNotEmpty(checkCommandNumberUnique(cmdNumber))) { //判断不为空进入
//                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "指令号重复了：" + cmdNumber);
//            }
//            if (EmptyUtils.isEmpty(tbOrder)) {
//                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "订单号不存在：" + command.getOrderNumber());
//            }
            if (EmptyUtils.isEmpty(cmdNumber) || EmptyUtils.isNotEmpty(checkCommandNumberUnique(cmdNumber))) {  //判断指令号为空或者重复的话就重新生产
                if (EmptyUtils.isNotEmpty(createBy)) {
                    while (true) {
                        String username = Objects.requireNonNull(QuickQuery.byOne(sysUserMapper, "username", createBy)).getDivCode();
                        if (EmptyUtils.isEmpty(checkCommandNumberUnique(cmdNumber(username)))) {//判断唯一
                            command.setCmdNumber(cmdNumber(username));
                            break;
                        }
                    }
                } else {
                    return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.MissingParameters);
                }
            }
            if (tbCommandMapper.insert(command) > 0) {
                Long[] orderId = command.getOrderId();  //拿到订单的id
                if (EmptyUtils.isNotEmpty(orderId)) {      //判断不为空进入
                    TbCmdOrder cmdOrder;
                    for (Long orderValue : orderId) {  //循环订单id
                        cmdOrder = new TbCmdOrder();
                        cmdOrder.setCmdId(command.getId());  //添加指令号的id
                        cmdOrder.setOid(orderValue);  //添加订单的id
                        tbCmdOrderMapper.insert(cmdOrder);  //添加
                    }
                    return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.AddedSuccessfully);
                } else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return ResultUtil.error(ResultEnum.UNKONW_ERROR, "未选择订单!");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.AddFailed);
    }

    /**
     * 修改指令信息
     *
     * @param command 指令信息
     * @return 结果
     */
    @Override
    @Transactional
    public Result<Object> updateCommand(TbCommand command) {
            Long id = command.getId();  //拿到修改指令的id
            TbCommand tbCommand = tbCommandMapper.selectById(id); //查询修改指令的指令管理
            TbOrder tbOrder = tbOrderService.checkOrderNumberUnique(command.getOrderNumber()); //根据订单号查询订单信息
            if (EmptyUtils.isEmpty(tbOrder)) { //订单号不存在
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "订单号不存在：" + command.getOrderNumber());
            }
            if (EmptyUtils.isNotEmpty(tbCommand)) { //判断指令号不等于空
//                long data = (command.getDelivery().getTime() - sdf.parse(sdf.format(tbCommand.getCreateTime())).getTime()) / (24 * 3600 * 1000);  //算出来距离几天
//                long paramsValue = Long.parseLong(paramsServiceService.get("CMD_DELIVERY").getParamsValue());  //交期
//                if (data < paramsValue) {
//                    return ResultUtil.success(ResultEnum.UNKONW_ERROR, "交期时间必须大于指令时间：" + paramsValue + "天");
//                }
                //指令号不一样
                //判断不为空进入
                if (!tbCommand.getCmdNumber().equals(command.getCmdNumber()))
                    if (EmptyUtils.isNotEmpty(checkCommandNumberUnique(command.getCmdNumber())))
                        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "指令号重复了：" + command.getCmdNumber());
                if (tbCommandMapper.updateById(command) > 0) { //修改成功

                    long tbOrderCount = 0L;  //计算订单id相等数
                    Long[] orderId = command.getOrderId(); //拿到订单id
                    if (EmptyUtils.isEmpty(orderId)) {
                        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "没有选择订单!");
                    }
                    List<TbCmdOrder> tbOrderList = new CopyOnWriteArrayList<>(listTbCmdOrderByCmdId(command.getId())); //查询指令下的订单
                    for (TbCmdOrder tb : tbOrderList) { //循环原先的订单id
                        for (Long orderValueId : orderId) { //循环传来的订单id
                            if (tb.getOid().equals(orderValueId)) { //判断相等
                                tbOrderList.remove(tb); //删除
                                tbOrderCount++; //加加
                            } else tbCmdOrderMapper.deleteById(tb.getId()); //不相等就删除之前的
                        }
                    }
                    if (tbOrderCount != orderId.length) { //如果一样就证明没修改过
                        tbOrderList = new CopyOnWriteArrayList<>(listTbCmdOrderByCmdId(command.getId())); //在查询一次订单下物料id
                        int result; //状态
                        TbCmdOrder TbCmdOrder; //关联表
                        for (Long orderValueId : orderId) { //循环传来的
                            result = 0;
                            for (TbCmdOrder tb : tbOrderList) { //循环原先的
                                if (tb.getOid().equals(orderValueId)) { //判断相等
                                    result = 1; //就等于1
                                    break;
                                }
                            }
                            if (result != 1) { //相等的不添加
                                TbCmdOrder = new TbCmdOrder(); //添加关联表
                                TbCmdOrder.setCmdId(command.getId());  //指令id
                                TbCmdOrder.setOid(orderValueId); //订单id
                                tbCmdOrderMapper.insert(TbCmdOrder);//添加关联表
                            }
                        }
                    }
                    return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyModified);
                }
            }else {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "该指令不存在!");
            }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.FailToEdit);
    }

    /**
     * 查询指令信息
     *
     * @param param 指令信息
     * @return 结果
     */
    @Override
    public Result<Object> selectCommandList(Map<String, String> param) {
        try {
            int pageNum = Integer.parseInt(param.get("page"));  //页码
            int limit = Integer.parseInt(param.get("limit")); //页数量
            if (EmptyUtils.isNotEmpty(pageNum) && EmptyUtils.isNotEmpty(limit)) {  //不等于空
//                Long[] prodId;
                Page<TbCommand> page = new Page<>(pageNum, limit); //分页
                IPage<TbCommand> iPage = tbCommandMapper.selectCommandList(page, param); //分页查询
                List<TbOrder> orderList; //创建订单计划
                List<TbMaterial> listMaterial; //创建物料
                List<TbCommand> records = new CopyOnWriteArrayList(iPage.getRecords());//指令列表
                for (TbCommand command : records) { //循环指令
                    orderList = new CopyOnWriteArrayList(tbCommandMapper.getOrderList(command.getId(), param.get("orderNumber"))); //查询指令下的订单,并赋值
                    command.setTbOrderList(orderList); //把订单添加到指令
                    if (EmptyUtils.isEmpty(orderList)) { //没有该订单就不查询出来
                        records.remove(command);  //清空
                        continue; //下一个循环
                    }
                    for (TbOrder tbOrder : orderList) { //循环订单
                        Long orderPcsTotal = 0L; //计划数
                        listMaterial = new CopyOnWriteArrayList(tbCommandMapper.getListMaterial(tbOrder.getId(), param.get("matlNumber"))); //查询订单下的物料
                        if (EmptyUtils.isEmpty(listMaterial)) { //没有该物料就不查询出来
                            records.remove(command);  //清空
                            orderList.remove(tbOrder);  //清空
                            continue; //下一个循环
                        }
                        tbOrder.setTbMaterial(listMaterial); //把物料添加到订单
                        //订单数不为空
                        for (TbMaterial material : listMaterial) //循环物料
                        {
                            material.setRawMatlList(tbRawMatlMapper.selectTbRawMatlById(null, material.getId()));  //根据物料id查询下面的原材料
                            long orderPcs = material.getOrderPcs();  //订单数
                            long finishQuantity = material.getFinishQuantity() == null ? 0 : material.getFinishQuantity();  //完成数量
                            long fpPcs = EmptyUtils.isEmpty(material.getFpPcs()) ? 0L : material.getFpPcs(); //成品数量
                            double wdWeight = EmptyUtils.isEmpty(material.getWdWeight()) ? 0 : material.getWdWeight();//水口重量
                            double matlWeight = EmptyUtils.isEmpty(material.getMatlWeight()) ? 0 : material.getMatlWeight();//物料单重
                            double needWeight = (matlWeight + wdWeight) * (orderPcs - fpPcs - finishQuantity);  //缺少重量
                            material.setNeedWeight(orderPcs <= fpPcs ? 0.0 : needWeight < 0 ? 0 : needWeight); //判断订单数小于成品需要数为0.0否者就水口重量+物料单重乘订单-成品数量
                            long lackPcs = orderPcs - fpPcs - finishQuantity;  //订单缺少数量
                            material.setLackPcs(orderPcs <= fpPcs ? 0 : lackPcs < 0 ? 0 : lackPcs); //判断订单数小于成品需要数为0
                            material.setWeight((matlWeight + wdWeight) * orderPcs); //所有重量
                            material.setUnFinishQuantity(orderPcs - finishQuantity);  //未完成数量
                            if (EmptyUtils.isNotEmpty(material.getOrderPcs()))
                                orderPcsTotal += material.getOrderPcs(); //加订单数
                        }
                        if (EmptyUtils.isNotEmpty(tbOrderMapper.tbOrderById(tbOrder.getId())))
                            tbOrder.setSelected(true);
                        tbOrder.setPlanNumber(orderPcsTotal);//计划数
                    }
                }


                //System.err.println(commandList);
//                for (TbCommand tb : iPage.getRecords()) {  //循环订单号
//                    List<TbCmdProd> tbCmdProds = listCmdProdListByCmdId(tb.getId());  //查询到指令号下面的生产计划
//                    int size = tbCmdProds.size();
//                    prodId = new Long[size];
//                    for (int tbCmdProdsIndex = 0; tbCmdProdsIndex < size; tbCmdProdsIndex++) { //循环生产计划
//                        prodId[tbCmdProdsIndex] = tbCmdProds.get(tbCmdProdsIndex).getProdId();  //拿到生产计划id
//                    }
//                    tb.setProdId(prodId); //用订单号算出生产计划数量
//                }
                return ResultUtil.success(ResultEnum.SUCCESS, records, iPage.getTotal()); //第二个参数 分页查询列表 第三个参数总数
            } else {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.MissingParameters);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR);
    }

    /**
     * 删除指令信息
     *
     * @param command 指令信息
     * @return 结果
     */
    @Override
    @Transactional
    public Result<Object> deleteCommand(TbCommand command) {
        try {

            int deleteIdCount = 0; //删除数量
            Long id = command.getId();  //删除id
            if (EmptyUtils.isNotEmpty(id)) { //不等于空
                if (EmptyUtils.isNotEmpty(tbCmdOrderMapper.getCmdById(id))) { //查询生产计划
                    return ResultUtil.error(ResultEnum.UNKONW_ERROR, "生产计划在使用不能删除!");
                }
                List<TbCmdOrder> tbCmdProds = listTbCmdOrderByCmdId(id);
                //循环订单
                for (TbCmdOrder tbCmdProd : tbCmdProds)
                    deleteIdCount = deleteIdCount + tbCmdOrderMapper.deleteById(tbCmdProd.getId());
                if (tbCmdProds.size() == deleteIdCount && tbCommandMapper.deleteById(command.getId()) > 0) {  //判断删除数量跟原始
                    return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyDeleted);
                }
            } else {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.MissingParameters);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.FailedToDelete);
    }

    /**
     * 根据订单查询
     *
     * @param orderNumber
     * @return
     */
    @Override
    public Result<Object> getOrderNumber(String orderNumber, String cmdNumber) {
        try {
            QueryWrapper<TbOrder> qw = new QueryWrapper<>();
            qw.like("order_number", orderNumber);
            List<TbOrder> orderList = new CopyOnWriteArrayList(tbOrderMapper.selectList(qw));  //查询到订单 解决并发
            TbCommand command;
            for (TbOrder order : orderList) {
                if (order.getCheckOrder().equals(1L)) if (!order.getApprove().equals(1L)) orderList.remove(order);
                command = tbCommandMapper.getOrder(order.getOrderNumber());//拿到已用的指令号
                if (EmptyUtils.isNotEmpty(command)) {
                    order.setDisabled(true);
                    if (EmptyUtils.isNotEmpty(tbCmdOrderMapper.getCmdOrderById(order.getId())))
                        order.setSelected(true);
                }

            }
            return ResultUtil.success(ResultEnum.SUCCESS, orderList); //成功！
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR);
    }

    /**
     * 生产指令号
     *
     * @param param
     * @return
     */
    @Override
    public Result<Object> productionCmdNumber(ClientParameters param) {
        try {
            String one = param.getOne(); //参数
            if (EmptyUtils.isNotEmpty(one)) {
                String username = Objects.requireNonNull(QuickQuery.byOne(sysUserMapper, "username", one)).getDivCode();
                return ResultUtil.success(ResultEnum.SUCCESS, cmdNumber(username));
            } else {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.MissingParameters);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR);
    }

    /**
     * 生产指令号
     */
    public String cmdNumber(String createBy) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd");  //转换
        cmdNumberIndex = cmdNumberIndex + 1;  //自增
        return createBy + formatter.format(new Date()) + cmdNumberIndex;
    }

    /**
     * 根据订单id查询
     */
    @Override
    public List<TbCmdOrder> getByOrderId(Long orderId) {
        QueryWrapper<TbCmdOrder> query = new QueryWrapper<>();
        query.eq("oid", orderId);
        return tbCmdOrderMapper.selectList(query);
    }

    /**
     * 指令号唯一
     */
    public TbCommand checkCommandNumberUnique(String cmdNumber) {
        QueryWrapper<TbCommand> qw = new QueryWrapper<>();
        qw.eq("cmd_number", cmdNumber);
        return tbCommandMapper.selectOne(qw);
    }

    /**
     * 根据根据指令id查询订单
     *
     * @return
     */
    public List<TbCmdOrder> listTbCmdOrderByCmdId(Long cmdId) {
        QueryWrapper<TbCmdOrder> qw = new QueryWrapper<>();
        qw.eq("cmd_id", cmdId);
        return tbCmdOrderMapper.selectList(qw);
    }
}
